package controller

import (
	"apiProject/api/expressAPI/interceptor"
	"apiProject/api/expressAPI/service"
	"apiProject/api/expressAPI/types/domain"
	"apiProject/api/expressAPI/types/param"
	"apiProject/api/response"
	"apiProject/api/utils"
	"encoding/json"
	"github.com/bytedance/sonic"
	"github.com/gorilla/mux"
	"io"
	"log"
	"net/http"
)

// ExpressController 快递控制器
type ExpressController struct {
	expressService service.ExpressServiceInterface // 快递服务接口
	userService    service.UserServiceInterface    // 用户服务接口
}

// ExpressControllerInit 快递控制器初始化
func ExpressControllerInit(e service.ExpressServiceInterface, u service.UserServiceInterface) *ExpressController {
	return &ExpressController{
		expressService: e,
		userService:    u,
	}
}

// RegisterRoutes 注册快递服务请求路由
func (e *ExpressController) RegisterRoutes(r *mux.Router) {
	// 新增
	r.HandleFunc("/express", e.handlerCrete).Methods("POST")
	// 查询详情
	r.HandleFunc("/express/detail", e.handlerDetail).Methods("GET")
	// 分页查询
	r.HandleFunc("/expressPage/list", e.handlerSelectPage).Methods("GET")
	// 查询
	r.HandleFunc("/express/{dataId}", e.handlerGet).Methods("GET")
	// 删除
	r.HandleFunc("/express/{dataId}", e.handlerDelete).Methods("DELETE")
	// 多条件查询分页
	r.HandleFunc("/expressPage/list", e.handlerSelectPageParam).Methods("POST")
	// 修改
	r.HandleFunc("/express/update", e.handlerUpdate).Methods("PUT")
	// 批量新增
	r.HandleFunc("/express/batchDelete", e.handlerBatchDelete).Methods("POST")
	// 批量新增
	r.HandleFunc("/express/batchAdd", interceptor.WithJWTAuthorization(e.handlerBatchInsert, e.userService)).Methods("POST")
}

func (e *ExpressController) handlerCrete(w http.ResponseWriter, r *http.Request) {
	var express *domain.Express

	/*if err := json.NewDecoder(r.Body).Decode(&express); err != nil {
		log.Println(err)
		response.WriteJson(w, response.FailMessageResp("新增失败"))
		return
	}*/

	body, err := io.ReadAll(r.Body)
	if err != nil {
		log.Printf("新增参数读取错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("新增失败"))
		return
	}
	defer r.Body.Close()

	//err = json.Unmarshal(body, &express)
	err = sonic.Unmarshal(body, &express)
	if err != nil {
		log.Printf("新增参数解析错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("新增失败"))
		return
	}

	t, err := e.expressService.CreateExpress(express)
	if err != nil {
		log.Printf("新增操作错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("新增失败"))
		return
	}
	response.WriteJson(w, response.OkDataResp(t))
}

func (e *ExpressController) handlerGet(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	var queryId = vars["dataId"]
	if queryId == "" {
		response.WriteJson(w, response.FailMessageResp("ID参数不能为空"))
		return
	}
	t, err := e.expressService.GetExpress(utils.ConvertToInt64(queryId))
	if err != nil {
		response.WriteJson(w, response.FailMessageResp("获取数据失败"))
		return
	}
	response.WriteJson(w, response.OkDataResp(t))
}

func (e *ExpressController) handlerDetail(w http.ResponseWriter, r *http.Request) {
	var dataId = r.URL.Query().Get("dataId")
	log.Printf("获取的参数：%s", dataId)
	if dataId == "" {
		response.WriteJson(w, response.FailMessageResp("ID参数不能为空"))
		return
	}
	id := utils.ConvertToInt64(dataId)
	t, err := e.expressService.GetExpress(id)
	if err != nil {
		log.Printf("获取详情数据错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("获取详情数据失败"))
		return
	}

	response.WriteJson(w, response.OkDataResp(t))
}

func (e *ExpressController) handlerSelectPage(w http.ResponseWriter, r *http.Request) {
	url := r.URL
	expressName := url.Query().Get("expressName")
	page := url.Query().Get("page")
	size := url.Query().Get("size")

	expressPage, totalRecords, totalPages, err := e.expressService.SelectExpressPage(expressName, page, size)
	if err != nil {
		return
	}
	/*pageDataMap := make(map[string]interface{})
	pageDataMap["content"] = expressPage
	pageDataMap["totalRecords"] = totalRecords
	pageDataMap["totalPages"] = totalPages
	response.WriteJson(w, response.OkDataResp(pageDataMap))*/

	response.WriteJson(w, response.OkDataResp(response.NewPageData(totalRecords, totalPages, expressPage)))
}

func (e *ExpressController) handlerSelectPageParam(w http.ResponseWriter, r *http.Request) {
	var searchParam param.ExpressSearchParam
	/*if err := json.NewDecoder(r.Body).Decode(&searchParam); err != nil {
		log.Println(err)
		response.WriteJson(w, response.FailMessageResp("查询失败"))
		return
	}*/
	// 单个新增数据量比较小使用io.ReadAll
	body, err := io.ReadAll(r.Body)
	if err != nil {
		log.Printf("获取分页错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("分页参数解析失败"))
		return
	}

	defer utils.CloseBodyError("快递分页请求", w, r)

	if err := sonic.Unmarshal(body, &searchParam); err != nil {
		log.Printf("sonic.Unmarshal错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("获取分页数据失败"))
		return
	}

	column, order := utils.HandlerColumnOrder(searchParam.Column, searchParam.Order)
	searchParam.Column = column
	searchParam.Order = order

	log.Println("快递分页查询参数===", searchParam)

	expressPage, totalRecords, totalPages, err := e.expressService.SelectExpressPageByParam(&searchParam)
	if err != nil {
		log.Printf("分页查询错误===%s+v", err)
		response.WriteJson(w, response.FailCodeMessageResp(http.StatusInternalServerError, "查询分页数据失败"))
		return
	}

	response.WriteJson(w, response.OkDataResp(response.NewPageData(totalRecords, totalPages, expressPage)))
}

func (e *ExpressController) handlerDelete(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	var queryId = vars["dataId"]
	if queryId == "" {
		response.WriteJson(w, response.FailMessageResp("ID参数不能为空"))
		return
	}
	t, err := e.expressService.DeleteById(utils.ConvertToInt64(queryId))
	if err != nil {
		log.Printf("删除操作错误===%s+v", err)
		response.WriteJson(w, response.FailCodeMessageResp(http.StatusInternalServerError, "删除失败"))
		return
	}
	response.WriteJson(w, response.OkDataResp(t))
}

func (e *ExpressController) handlerUpdate(w http.ResponseWriter, r *http.Request) {
	body, err := io.ReadAll(r.Body)
	if err != nil {
		log.Printf("读取更新参数错误===%s+v", err)
		response.WriteJson(w, response.FailCodeMessageResp(http.StatusInternalServerError, "获取参数失败"))
		return
	}
	defer utils.CloseBodyError("快递更新请求", w, r)

	var express *domain.Express
	err = json.Unmarshal(body, &express)
	if err != nil {
		log.Printf("解析更新参数错误===%s+v", err)
		response.WriteJson(w, response.FailCodeMessageResp(http.StatusInternalServerError, "解析参数失败"))
		return
	}

	t, err := e.expressService.UpdateExpress(express)
	if err != nil {
		log.Printf("更新操作错误===%s+v", err)
		response.WriteJson(w, response.FailCodeMessageResp(http.StatusInternalServerError, "更新失败"))
		return
	}
	response.WriteJson(w, response.OkDataResp(t))
}

func (e *ExpressController) handlerBatchDelete(w http.ResponseWriter, r *http.Request) {
	body, err := io.ReadAll(r.Body)
	if err != nil {
		log.Printf("批量删除参数读取错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("批量删除参数获取失败"))
		return
	}
	defer utils.CloseBodyError("快递批量删除请求", w, r)

	var ids []string
	err = json.Unmarshal(body, &ids)
	if err != nil {
		log.Printf("批量删除参数解析错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("批量删除参数解析失败"))
		return
	}

	if len(ids) == 0 {
		response.WriteJson(w, response.FailMessageResp("请至少选择一条数据"))
		return
	}

	if len(ids) > 20 {
		response.WriteJson(w, response.FailMessageResp("批量删除单次操作不能超过20条"))
		return
	}
	t, err := e.expressService.BatchDeleteByIds(ids)
	if err != nil {
		log.Printf("批量删除参数操作错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("批量删除失败"))
		return
	}
	response.WriteJson(w, response.OkDataResp(t))
}

// handlerBatchInsert 批量新增
func (e *ExpressController) handlerBatchInsert(w http.ResponseWriter, r *http.Request) {
	var list []*domain.Express
	// 大批量情况下使用json.NewDecoder与Decode
	if err := json.NewDecoder(r.Body).Decode(&list); err != nil {
		log.Printf("批量新增参数解析错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("批量新增参数解析失败"))
		return
	}

	defer utils.CloseBodyError("快递批量新增请求", w, r)

	if len(list) == 0 {
		response.WriteJson(w, response.FailMessageResp("批量新增参数不能为空"))
		return
	}

	if len(list) > 1000 {
		response.WriteJson(w, response.FailMessageResp("批量新增单次最多不能超过1000条"))
		return
	}

	t, err := e.expressService.BatchCreateExpress(list)
	if err != nil {
		log.Printf("批量新增操作错误===%s+v", err)
		response.WriteJson(w, response.FailMessageResp("批量新增失败"))
		return
	}
	response.WriteJson(w, response.OkDataResp(t))
}
